package cn.crex1.xiaomi.util;

import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JsonUtils {

	@SuppressWarnings("deprecation")
	private static ObjectMapper objectMapper = new ObjectMapper()
			.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // 禁止使用出现未知属性之时，抛出异常
			.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
			.setSerializationInclusion(Include.NON_NULL)
			.setSerializationInclusion(Include.NON_DEFAULT).setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
			.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);// 转化后的json的key命名格式

	/**
	 * 从请求中获取json字符串
	 * 
	 * @param <T>
	 * 
	 * @param request
	 * @param clazz
	 * @return
	 */
	public static <T> Object readJsonByRequest(HttpServletRequest request, Class<?> clazz) {
		try {
			return objectMapper.readValue(request.getInputStream(), clazz);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将对象转换成json字符串
	 * 
	 * @param <T>
	 * 
	 * @param object
	 * @return
	 */
	public static <T> String writeStringByObject(T t) {
		try {
			return objectMapper.writeValueAsString(t);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 从字符串中读取对象
	 * 
	 * @param str
	 * @param clazz
	 * @return
	 */
	public static <T> Object readObjectByString(String str, Class<T> clazz) {
		try {
			return objectMapper.readValue(str, clazz);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return clazz;
	}

	public static <E> E readObjectByString(String str, JavaType collectionType) {
		try {
			return objectMapper.readValue(str, collectionType);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取泛型的Collection Type
	 * 
	 * @param collectionClass
	 *            泛型的Collection
	 * @param elementClasses
	 *            元素类
	 * @return JavaType Java类型
	 * @since 1.0
	 */
	public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
		return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
	}

	/**
	 * 将json字符串写入响应
	 * 
	 * @param response
	 * @param jsonString
	 */
	public static void writeJsonStringByResponse(HttpServletResponse response, String jsonString) {
		try {
			response.setContentType("text/html;charset=utf-8");
			Writer out = response.getWriter();
			out.write(jsonString);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将map转化为json字符串
	 * 
	 * @param jsonmap
	 * @return
	 */
	public static String writeJsonStringByMap(Map<String, Object> jsonmap) {
		return JsonUtils.writeStringByObject(jsonmap);
	}
	/**
	 * 查找值
	 * @param jsonstring
	 * @param key
	 * @param value
	 * @return
	 */
	public static List<String> findValuesbyJsonString(String jsonstring, String key, Object value) {
		List<String> jsonList = new ArrayList<>();
		JsonNode node = null;
		try {
			node = objectMapper.readTree(jsonstring);
			jsonList = jsonNodePaser(node, key, value);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonList;

	}
	/**
	 * json字符串解析 获取的特定值的集合
	 * @param node
	 * @param key
	 * @param value
	 * @return
	 */
	public static List<String> jsonNodePaser(JsonNode node, String key, Object value) {
		List<String> jsonList = new ArrayList<>();
		if (node.isArray()) {
			Iterator<JsonNode> it = node.iterator();
			while (it.hasNext()) {
				JsonNode jsonNode = it.next();
				if (jsonNode.isValueNode()) {
					jsonList.add(node.toString());
				}
				if (jsonNode.isObject()) {
					Iterator<Entry<String, JsonNode>> it1 = jsonNode.fields();
					while (it1.hasNext()) {
						Entry<String, JsonNode> entry = it1.next();
						if (entry.getKey().equals(key) && entry.getValue().asText().equals(value)) {
							jsonList.add(jsonNode.toString());
						}
					}
				}
			}
		}
		return jsonList;
	}

	public static void main(String[] args) {
		try {
			String string = RedisUtil.Strings.get("cplist");
			List<String> values = JsonUtils.findValuesbyJsonString(string, "category_id","2");
			System.out.println(values.toString());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
